import plugin from "../../lib/plugins/plugin.js";
import axios from "axios";
import { APIS } from "./config.js";
import { saveSpeedData, getTodaySpeedData } from "./utils.js";

export class DeepSeekPlugin extends plugin {
  /**
   * 构造函数，初始化插件配置
   * @description 配置包含：
   * - 4种消息匹配规则（#ask命令/@机器人/回复消息/#speed测速）
   * - 白名单用户ID列表
   * - API密钥检查开关配置
   */
  constructor() {
    super({
      name: "DeepSeek问答",
      dsc: "调用多平台DeepSeek API进行问答",
      event: "message",
      priority: 1000,
      rule: [
        {
          reg: "^#ask", // 匹配以#ask开头的消息
          fnc: "handleAsk", // 调用handleAsk方法处理
          log: true,
        },
        {
          reg: "^\\[CQ:at,qq=\\d+\\]", // 匹配@机器人的消息
          fnc: "handleAt", // 调用handleAt方法处理@机器人的消息
          log: true,
        },
        {
          reg: "^\\[CQ:reply,id=-\\d+\\]", // 匹配引用机器人的消息
          fnc: "handleQuote", // 调用handleQuote方法处理机器人的消息
          log: true,
        },
        {
          reg: "^#speed", // 匹配以#speed开头的消息
          fnc: "handleSpeed", // 调用handleSpeed方法处理
          log: true,
        },
        {
          reg: "^#R1speed",
          fnc: "handleR1Speed",
          log: true,
        },
        {
          reg: "^#V3speed",
          fnc: "handleV3Speed",
          log: true,
        },
        {
          reg: "^#logspeed",
          fnc: "handleLogSpeed",
          log: true,
        },
      ],
    });

    this.whitelist = [2573270370, 987654321, 3630567855, 2644048301]; // 白名单用户ID列表

    // 配置项，控制是否启用全局 Key 检查
    this.cfg = {
      enableKeyCheck: true,
      speedTestInterval: 5, // 定时测速间隔，单位：分钟
    };

    // 启动定时任务
    this.startSpeedTestSchedule();

    // 确保目录被提前创建
    this.ensureSpeedDataDirExists();

    // 添加插件载入完成提示
    console.log("----------------------------------------");
    console.log("DeepSeek插件载入成功");
    console.log("使用说明：发送 #ask 进行提问，或 #speed 测试API速度");
    console.log("----------------------------------------");
    console.log(" ╱|、");
    console.log("(˚ˎ 。7");
    console.log(" |、˜〵");
    console.log("じしˍ,)ノ");
  }

  /**
   * 确保测速数据目录存在
   */
  async ensureSpeedDataDirExists() {
    try {
      await saveSpeedData({ name: "目录检查", time: 0, speed: 0, success: true, error: null, totalTokens: 0, costTime: 0 });
      console.log("[DeepSeek] 测速数据目录检查完成");
    } catch (error) {
      console.error(`[DeepSeek] 测速数据目录创建失败: ${error.message}`);
    }
  }

  /**
   * 启动定时测速任务
   */
  async startSpeedTestSchedule() {
    // 立即执行一次
    await this.silentApiSpeedTest();

    // 使用配置项中的间隔
    setInterval(async () => {
      await this.silentApiSpeedTest();
    }, this.cfg.speedTestInterval * 60 * 1000);
  }

  /**
   * 权限验证方法
   * @returns {boolean} 是否通过验证
   * @description 检查用户ID是否在预配置的白名单中
   */
  checkPermission() {
    const userId = this.e.user_id;
    if (!this.whitelist.includes(userId)) {
      this.e.reply(`[权限拒绝] QQ号 ${userId} 未在白名单中`);
      return false;
    }
    return true;
  }

  /**
   * 处理#ask命令
   * @returns {Promise<boolean>} 是否处理完成
   * @description 提取#ask后的提问内容进行问答处理
   */
  async handleAsk() {
    if (!this.checkPermission()) return true;

    const prompt = this.e.msg.replace(/^#ask/, "").trim();
    if (!prompt) {
      await this.e.reply("请输入要提问的内容，例如：#ask 什么是人工智能？");
      return true;
    }
    return this.processQuery(prompt);
  }

  /**
   * 处理@机器人的消息
   * @returns {Promise<boolean>} 是否处理完成
   * @description 移除@标记后提取有效提问内容
   */
  async handleAt() {
    if (!this.checkPermission()) return true;

    const prompt = this.e.msg.replace(/\[CQ:at,qq=\d+\]/g, "").trim();
    if (prompt) {
      return this.processQuery(prompt);
    }
    return true;
  }

  async handleQuote() {
    if (!this.checkPermission()) return true;

    const quoteMsg = await this.e.getQuoteMessage();
    if (quoteMsg && quoteMsg.sender.user_id === this.e.self_id) {
      const prompt = this.e.msg.replace(/\[CQ:reply,id=-\d+\]/g, "").trim();
      if (prompt) {
        return this.processQuery(prompt);
      }
    }
    return true;
  }

  async processQuery(prompt) {
    try {
      await this.e.reply("正在思考中，请稍候...", true);

      // 随机选择API供应商
      const api = APIS[Math.floor(Math.random() * APIS.length)];
      console.log(`[API选择] 使用 ${api.name}`);

      const startTime = Date.now();
      const response = await axios.post(
        api.url,
        {
          model: api.model,
          messages: [
            { role: "system", content: `你是一个ai助手` },
            { role: "user", content: prompt },
          ],
          temperature: 0.7,
          max_tokens: api.max_tokens || 4096, // 非Pro版本使用4096
        },
        {
          timeout: 100000,
          headers: {
            Authorization: `Bearer ${api.key}`,
            "Content-Type": "application/json",
            ...(api.name.includes("硅基流动") && {
              "X-API-Source": "QQ-Bot",
            }),
          },
        }
      );

      // 统一token计算
      const tokenPath = api.tokenPath.split(".");
      const totalTokens =
        tokenPath.reduce((obj, key) => obj?.[key], response.data) ||
        Math.round(response.data.choices[0].message.content.length / 3);
      const costTime = (Date.now() - startTime) / 1000;
      const tokenSpeed = totalTokens / costTime;

      let result = response.data.choices[0].message.content
        .replace(/<think>[\s\S]*?<\/think>/g, "")
        .trim();

      await this.e.reply(
        [
          `【${api.name}】生成速度 ${tokenSpeed.toFixed(1)} token/s\n`,
          result,
        ],
        true
      );
    } catch (error) {
      console.error("[DeepSeek] 请求失败:", error);
      let errorMsg = "服务暂时不可用，请稍后再试";
      if (error.code === "ECONNABORTED") {
        errorMsg = "请求超时，可能是API服务未响应";
      } else if (error.response?.status === 401) {
        errorMsg = "API密钥验证失败，请检查密钥配置";
      } else if (error.response?.status === 404) {
        errorMsg = "API端点不存在，请检查服务地址";
      } else if (error.response?.data?.error?.message) {
        errorMsg = `服务错误: ${error.response.data.error.message}`;
      }
      await this.e.reply(errorMsg, true);
    }
    return true;
  }

  async handleSpeed() {
    if (!this.checkPermission()) return true;
    return this.testApiSpeed("评价一下OpenAI");
  }

  async handleR1Speed() {
    if (!this.checkPermission()) return true;
    return this.testApiSpeed("评价一下OpenAI", "R1");
  }

  async handleV3Speed() {
    if (!this.checkPermission()) return true;
    return this.testApiSpeed("评价一下OpenAI", "V3");
  }

  async silentApiSpeedTest() {
    const now = new Date();
    console.log(`[DeepSeek] 定时测速开始: ${now.toLocaleString()}`);
    await this.testApiSpeed("评价一下OpenAI", null, true); // 静默模式
  }

  async handleLogSpeed() {
    if (!this.checkPermission()) return true;

    const speedData = await getTodaySpeedData();
    if (!speedData || speedData.length === 0) {
      await this.e.reply("今日暂无测速记录", true);
      return true;
    }

    let totalTokens = 0;
    let totalTime = 0;
    let timeoutCount = 0;

    speedData.forEach((item) => {
      totalTokens += item.totalTokens;
      totalTime += item.costTime;
      if (item.error) {
        timeoutCount++;
      }
    });

    const avgSpeed = totalTokens / totalTime;
    const replyText = [
      "📊 今日测速结果：",
      `总消耗Token: ${totalTokens}`,
      `总耗时: ${totalTime.toFixed(2)} 秒`,
      `平均速度: ${avgSpeed.toFixed(1)} token/s`,
      `超时次数: ${timeoutCount} 次`,
    ].join("\n");

    await this.e.reply(replyText, true);
    return true;
  }

  async testApiSpeed(prompt, type = null, silent = false) {
    if (!silent) {
      await this.e.reply("🔄 开始测试API响应速度，请稍候...", true);
    }

    try {
      let apisToTest = APIS;
      if (type) {
        apisToTest = APIS.filter((api) => api.type === type);
        if (apisToTest.length === 0) {
          if (!silent) {
            await this.e.reply(`⚠️ 没有找到类型为 ${type} 的模型`, true);
          }
          return true;
        }
      }

      const missingKeys = [];
      let validApis = [];
      if (this.cfg.enableKeyCheck) {
        for (const api of apisToTest) {
          if (!api.key) {
            missingKeys.push(api.vendor);
          } else {
            validApis.push(api);
          }
        }
      } else {
        validApis = apisToTest;
      }

      const testRequests = validApis.map((api) =>
        this.testSingleApi(api, prompt)
      );
      const results = await Promise.all(testRequests);

      // 保存测速数据
      for (const result of results) {
        await saveSpeedData(result);
      }

      if (!silent) {
        const replyText = [
          "📊 API响应速度测试结果：",
          ...results.map((r) =>
            r.success
              ? `✔️ ${r.name}: ${r.time}s (${r.speed} token/s)`
              : `❌ ${r.name}: 请求失败 (${r.error})`
          ),
        ].join("\n");
        await this.e.reply(replyText, true);
      }

      if (this.cfg.enableKeyCheck && missingKeys.length > 0) {
        if (!silent) {
          await this.e.reply(
            `⚠️ 您没有配置以下供应商的 Key：${missingKeys.join(", ")}`,
            true
          );
        }
      }
    } catch (error) {
      if (!silent) {
        await this.e.reply("⚠️ 测速过程中发生意外错误", true);
      }
      console.error("[SpeedTest] Error:", error);
    }
    return true;
  }

  async testSingleApi(api, prompt) {
    const startTime = Date.now();
    let totalTokens = 0;
    let costTime = 0;

    try {
      console.log(`[测速] 测试 ${api.name}`, {
        model: api.model,
        key: api.key.slice(0, 6) + "******",
      });

      const payload = {
        model: api.model,
        messages: [
          { role: "system", content: "响应速度测试" },
          { role: "user", content: prompt },
        ],
        temperature: 0.2,
        max_tokens: api.max_tokens || 4096,
      };

      const response = await axios.post(api.url, payload, {
        timeout: 60000,
        headers: {
          Authorization: `Bearer ${api.key}`,
          "Content-Type": "application/json",
          ...(api.name.includes("硅基流动") && {
            "X-API-Source": "SpeedTest",
          }),
        },
      });

      const tokenPath = api.tokenPath.split(".");
      totalTokens =
        tokenPath.reduce((obj, key) => obj?.[key], response.data) ||
        Math.round(response.data.choices[0].message.content.length / 3);
      costTime = (Date.now() - startTime) / 1000;

      return {
        name: api.name,
        time: costTime.toFixed(2),
        speed: (totalTokens / costTime).toFixed(1),
        success: true,
        error: null,
        totalTokens: totalTokens,
        costTime: costTime,
      };
    } catch (error) {
      costTime = (Date.now() - startTime) / 1000;
      return {
        name: api.name,
        time: costTime.toFixed(2),
        speed: 0,
        success: false,
        error: this.parseError(error),
        totalTokens: totalTokens,
        costTime: costTime,
      };
    }
  }

  parseError(error) {
    if (error.code === "ECONNABORTED") return "请求超时";
    if (error.response?.status) return `HTTP ${error.response.status}`;
    if (error.response?.data?.error?.code)
      return `错误码 ${error.response.data.error.code}`;
    return error.message?.split("\n")[0] || "未知错误";
  }
}